package com.nbcio.modules.erp.material.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbcio.common.core.domain.R;
import com.nbcio.modules.erp.material.domain.ErpMaterial;
import com.nbcio.modules.erp.material.service.IErpMaterialService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;
import com.alibaba.excel.EasyExcel;
import com.nbcio.modules.erp.material.excel.MaterialExportDTO;

@Tag(name = "物料管理")
@RestController
@RequestMapping("/erp/material")
@RequiredArgsConstructor
public class ErpMaterialController {

    private final IErpMaterialService materialService;

    @GetMapping("/page")
    public R<IPage<ErpMaterial>> page(@RequestParam int pageNum,
                                      @RequestParam int pageSize,
                                      @RequestParam(required = false) String materialCode,
                                      @RequestParam(required = false) String materialName,
                                      @RequestParam(required = false) Integer status,
                                      @RequestParam(required = false) Integer enableBatch,
                                      @RequestParam(required = false) Integer enableSerial,
                                      @RequestParam(required = false) String startTime,
                                      @RequestParam(required = false) String endTime) {
        LambdaQueryWrapper<ErpMaterial> qw = new LambdaQueryWrapper<>();
        if (materialCode != null && !materialCode.isEmpty()) {
            qw.like(ErpMaterial::getMaterialCode, materialCode);
        }
        if (materialName != null && !materialName.isEmpty()) {
            qw.like(ErpMaterial::getMaterialName, materialName);
        }
        if (status != null) {
            qw.eq(ErpMaterial::getStatus, status);
        }
        if (enableBatch != null) {
            qw.eq(ErpMaterial::getEnableBatch, enableBatch);
        }
        if (enableSerial != null) {
            qw.eq(ErpMaterial::getEnableSerial, enableSerial);
        }
        if (startTime != null && endTime != null && !startTime.isEmpty() && !endTime.isEmpty()) {
            qw.between(ErpMaterial::getCreateTime, startTime, endTime);
        }
        IPage<ErpMaterial> page = materialService.page(Page.of(pageNum, pageSize), qw);
        return R.ok(page);
    }

    @GetMapping("/{id}")
    public R<ErpMaterial> get(@PathVariable("id") String id) {
        ErpMaterial data = materialService.getById(Long.parseLong(id));
        return R.ok(data);
    }

    @PostMapping
    public R<Boolean> create(@RequestBody ErpMaterial dto) {
        return R.ok(materialService.save(dto));
    }

    @PutMapping("/{id}")
    public R<Boolean> update(@PathVariable("id") String id, @RequestBody ErpMaterial dto) {
        dto.setMaterialId(Long.parseLong(id));
        return R.ok(materialService.updateById(dto));
    }

    @DeleteMapping("/{id}")
    public R<Boolean> remove(@PathVariable("id") String id) {
        return R.ok(materialService.removeById(Long.parseLong(id)));
    }

    @PostMapping("/batch-delete")
    public R<Boolean> batchDelete(@RequestBody List<String> ids) {
        List<Long> longIds = ids.stream().map(Long::parseLong).collect(Collectors.toList());
        return R.ok(materialService.removeByIds(longIds));
    }

    @GetMapping("/export")
    public void export(HttpServletResponse response,
                       @RequestParam(required = false) String materialCode,
                       @RequestParam(required = false) String materialName,
                       @RequestParam(required = false) Integer status,
                       @RequestParam(required = false) Integer enableBatch,
                       @RequestParam(required = false) Integer enableSerial,
                       @RequestParam(required = false) String startTime,
                       @RequestParam(required = false) String endTime,
                       @RequestParam(required = false) List<String> ids,
                       @RequestParam(required = false) List<String> columns) throws Exception {
        LambdaQueryWrapper<ErpMaterial> qw = new LambdaQueryWrapper<>();
        if (materialCode != null && !materialCode.isEmpty()) { qw.like(ErpMaterial::getMaterialCode, materialCode); }
        if (materialName != null && !materialName.isEmpty()) { qw.like(ErpMaterial::getMaterialName, materialName); }
        if (status != null) { qw.eq(ErpMaterial::getStatus, status); }
        if (enableBatch != null) { qw.eq(ErpMaterial::getEnableBatch, enableBatch); }
        if (enableSerial != null) { qw.eq(ErpMaterial::getEnableSerial, enableSerial); }
        if (startTime != null && endTime != null && !startTime.isEmpty() && !endTime.isEmpty()) { qw.between(ErpMaterial::getCreateTime, startTime, endTime); }
        if (ids != null && !ids.isEmpty()) { qw.in(ErpMaterial::getMaterialId, ids.stream().map(Long::parseLong).toList()); }
        List<ErpMaterial> list = materialService.list(qw);
        List<MaterialExportDTO> rows = list.stream().map(it -> {
            MaterialExportDTO dto = new MaterialExportDTO();
            dto.setMaterialCode(it.getMaterialCode());
            dto.setMaterialName(it.getMaterialName());
            dto.setUomId(it.getUomId() == null ? null : String.valueOf(it.getUomId()));
            dto.setEnableBatchText(it.getEnableBatch() != null && it.getEnableBatch() == 1 ? "是" : "否");
            dto.setEnableSerialText(it.getEnableSerial() != null && it.getEnableSerial() == 1 ? "是" : "否");
            dto.setStatusText(it.getStatus() != null && it.getStatus() == 1 ? "启用" : "停用");
            dto.setBarcode(it.getBarcode());
            dto.setRemark(it.getRemark());
            dto.setCreateTime(it.getCreateTime());
            return dto;
        }).toList();
        String fileName = URLEncoder.encode("物料列表.xlsx", StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
        var writer = EasyExcel.write(response.getOutputStream(), MaterialExportDTO.class);
        if (columns != null && !columns.isEmpty()) {
            writer.includeColumnFieldNames(new java.util.HashSet<>(columns));
        }
        writer.sheet("物料").doWrite(rows);
    }

    @GetMapping("/ids")
    public R<List<String>> ids(@RequestParam(required = false) String materialCode,
                               @RequestParam(required = false) String materialName,
                               @RequestParam(required = false) Integer status,
                               @RequestParam(required = false) Integer enableBatch,
                               @RequestParam(required = false) Integer enableSerial,
                               @RequestParam(required = false) String startTime,
                               @RequestParam(required = false) String endTime) {
        LambdaQueryWrapper<ErpMaterial> qw = new LambdaQueryWrapper<>();
        if (materialCode != null && !materialCode.isEmpty()) { qw.like(ErpMaterial::getMaterialCode, materialCode); }
        if (materialName != null && !materialName.isEmpty()) { qw.like(ErpMaterial::getMaterialName, materialName); }
        if (status != null) { qw.eq(ErpMaterial::getStatus, status); }
        if (enableBatch != null) { qw.eq(ErpMaterial::getEnableBatch, enableBatch); }
        if (enableSerial != null) { qw.eq(ErpMaterial::getEnableSerial, enableSerial); }
        if (startTime != null && endTime != null && !startTime.isEmpty() && !endTime.isEmpty()) { qw.between(ErpMaterial::getCreateTime, startTime, endTime); }
        List<String> idList = materialService.list(qw).stream().map(it -> String.valueOf(it.getMaterialId())).collect(Collectors.toList());
        return R.ok(idList);
    }
}


